import ctypes

# 链接
myLib = ctypes.CDLL("./lib/maze.dll")
solveMazeByAStar = myLib.solveMazeByAStar
solveMazeByDFS = myLib.solveMazeByDFS
solveMazeByBFS = myLib.solveMazeByBFS

# DynamicArray 动态数组
arrayType = ctypes.c_void_p


class DynamicArray(ctypes.Structure):
    _fields_ = [
        ("size", ctypes.c_int),
        ("capacity", ctypes.c_int),
        ("array", ctypes.POINTER(arrayType)),
    ]


# Stack 栈
class stack(ctypes.Structure):
    _fields_ = [("top", ctypes.c_int), ("array", ctypes.POINTER(DynamicArray))]


# 定义函数的返回类型和参数类型
solveMazeByDFS.restype = ctypes.POINTER(ctypes.POINTER(stack))
solveMazeByDFS.argtypes = (
    ctypes.POINTER(ctypes.POINTER(ctypes.c_int)),
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
)

solveMazeByBFS.restype = ctypes.POINTER(ctypes.POINTER(stack))
solveMazeByBFS.argtypes = (
    ctypes.POINTER(ctypes.POINTER(ctypes.c_int)),
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
)

solveMazeByAStar.restype = ctypes.POINTER(ctypes.POINTER(stack))
solveMazeByAStar.argtypes = (
    ctypes.POINTER(ctypes.POINTER(ctypes.c_int)),
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
    ctypes.c_int,
)
"""------------------------------------------------------"""


def getOutMaze(maze, startX, startY, endX, endY, method="DFS"):
    c_maze_ptr = (ctypes.POINTER(ctypes.c_int) * len(maze))()
    for i, row in enumerate(maze):
        c_row = (ctypes.c_int * len(row))(*row)
        c_maze_ptr[i] = ctypes.cast(c_row, ctypes.POINTER(ctypes.c_int))

    if method == "DFS":
        solver = solveMazeByDFS
    elif method == "BFS":
        solver = solveMazeByBFS
    elif method == "A*":
        solver = solveMazeByAStar
    else:
        raise ValueError("Invalid method")
    result = solver(c_maze_ptr, len(maze), len(maze[0]), startX, startY, endX, endY)

    # 将 result 转换为 Python 数组
    totalPath = result[0].contents.array.contents.array
    totalPath = ctypes.cast(totalPath, ctypes.POINTER(ctypes.POINTER(ctypes.c_int)))
    totalPathLength = result[0].contents.top + 1

    totalPathLi = [[0] * 2 for _ in range(totalPathLength)]
    for i in range(totalPathLength):
        totalPathLi[i][0] = totalPath[i][0]
        totalPathLi[i][1] = totalPath[i][1]

    s = result[1].contents.array.contents.array
    s = ctypes.cast(s, ctypes.POINTER(ctypes.POINTER(ctypes.c_int)))
    sLength = result[1].contents.top + 1

    sLi = [[0] * 2 for _ in range(sLength)]
    for i in range(sLength):
        sLi[i][0] = s[i][0]
        sLi[i][1] = s[i][1]

    return [totalPathLi, sLi]


# if __name__ == "__main__":
#     maze = [[5] * 17 for _ in range(17)]
#     print(list(reversed(getOutMaze(maze, 0, 0, 16, 16, "A*")[1])))
